#ifndef _H_IBMS_IN_
#define _H_IBMS_IN_

#include "ibp_util.h"

#include "IDL_ibms_conf.dsc.h"

extern char     *g_ibp_ibms_kernel_version ;

#define MAX_EPOLL_EVENTS		10000

#define URI_SHOW_NODES			"/show_nodes"
#define URI_SHOW_APPS			"/show_apps"
#define URI_SHOW_PROJECTS		"/show_projects"
#define URI_SHOW_NODES_CHANGED		"/show_nodes_changed"
#define URI_SHOW_SESSIONS		"/show_sessions"

#define URI_ADD_NODE			"/add_node"
#define URI_SET_NODE			"/set_node"
#define URI_REMOVE_NODE			"/remove_node"
#define URI_ADD_NODE_HOST		"/add_node_host"
#define URI_REMOVE_NODE_HOST		"/remove_node_host"
#define URI_ADD_APP			"/add_app"
#define URI_SET_APP			"/set_app"
#define URI_REMOVE_APP			"/remove_app"
#define URI_ADD_PROJECT			"/add_project"
#define URI_SET_PROJECT			"/set_project"
#define URI_REMOVE_PROJECT		"/remove_project"
#define URI_COMMIT_CHANGED		"/commit_changed"

#define HTTP_BODY_NOT_FOUND		"not found"
#define HTTP_BODY_FOUND			"found"

struct NoticeNodeChanged
{
	char				node[ IBP_MAXLEN_NODE + 1 ] ;
	
	struct list_head		this_node ;
} ;

struct IbmsNodeHost
{
	char			ip[ IBP_MAXLEN_NODE_IP + 1 ] ;
	int			port ;
#if 0
	int			invalid ;
#endif
	
	int			alive_connections ;
	
	struct rb_node		node_host_rbnode ;
} ;

struct IbmsNode
{
	char			node[ IBP_MAXLEN_NODE + 1 ] ;
	int			invalid ;
	
	struct rb_root		node_hosts_rbtree ;
	
	struct rb_node		node_rbnode ;
} ;

struct IbmsApp
{
	char			app[ IBP_MAXLEN_APP + 1 ] ;
	char			desc[ IBP_MAXLEN_APP_DESC + 1 ] ;
	char			bin[ IBP_MAXLEN_APP_BIN + 1 ] ;
	int			timeout ;
	int			timeout2 ;
	int			invalid ;
	
	struct rb_node		app_rbnode ;
} ;

struct IbmsProject
{
	char			project[ IBP_MAXLEN_PROJECT + 1 ] ;
	char			*nodes ;
	char			*apps ;
	
	struct rb_node		project_rbnode ;
} ;

struct ListenSession
{
	struct NetAddress	netaddr ;
} ;

struct PipeSession
{
	int			pipe_fds[ 2 ] ;
} ;

#define ACCEPTEDSESSION_ROLE_UNKNOWN_IDENTITY	1
#define ACCEPTEDSESSION_ROLE_IBMS		2
#define ACCEPTEDSESSION_ROLE_IBMA		3
#define ACCEPTEDSESSION_ROLE_IBAS		4

#define ACCEPTEDSESSION_DO_FETCH_CONFIG		1
#define ACCEPTEDSESSION_DO_KEEP_SILENT		2
#define ACCEPTEDSESSION_DO_DOWNLOAD_CONFIG	3

struct AcceptedSession
{
	int			role ;
	int			do_what ;
	
	struct NetAddress	netaddr ;
	
	struct HttpEnv		*http ;
	struct HttpSecureEnv	*http_secure_env ;
	struct IbmsNode		node ;
	struct IbmsNodeHost	node_host ;
	
	struct list_head	this_node ;
} ;

struct CommandParameter
{
	char			*_action ;
	char			*_show ;
	char			*__node ;
	char			*__invalid ;
	char			*__ip ;
	char			*__port ;
	char			*__app ;
	char			*__desc ;
	char			*__bin ;
	char			*__timeout ;
	char			*__timeout2 ;
	char			*__project ;
	char			*__nodes ;
	char			*__apps ;
} ;

struct IbmsEnv
{
	struct CommandParameter		cmd_param ;
	
	char				*ibms_conf_filename ;
	char				ibms_conf_pathfilename[ IBP_MAXLEN_FILENAME + 1 ] ;
	
	ibms_conf			ibms_conf ;
	char				nodes_conf_pathfilename[ IBP_MAXLEN_FILENAME + 1 ] ;
	char				apps_conf_pathfilename[ IBP_MAXLEN_FILENAME + 1 ] ;
	char				projects_conf_pathfilename[ IBP_MAXLEN_FILENAME + 1 ] ;
	
	struct rb_root			nodes_rbtree ;
	struct rb_root			apps_rbtree ;
	struct rb_root			projects_rbtree ;
	
	struct NoticeNodeChanged	notice_nodes_changed_list ;
	
	int				epoll_fd ;
	
	struct ListenSession		listen_session ;
	struct PipeSession		pipe_session ;
	struct AcceptedSession		accepted_session_list ;
} ;

int LoadConfig( struct IbmsEnv *p_env );

int InitEnvironment( struct IbmsEnv *p_env );
void CleanEnvironment( struct IbmsEnv *p_env );

int _monitor( void *pv );

int worker( struct IbmsEnv *p_env );

int OnAcceptingSocket( struct IbmsEnv *p_env , struct ListenSession *p_listen_session );
void OnClosingSocket( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnReceivingSocket( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnSendingSocket( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );

#if 0
int NoticeNodesInvalid( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
#endif
int OnProcess( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessShowNodes( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessShowApps( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessShowProjects( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessShowNodesChanged( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessShowSessions( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessAddNode( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessSetNode( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessRemoveNode( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessAddNodeHost( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessRemoveNodeHost( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessAddApp( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessSetApp( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessRemoveApp( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessAddProject( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessSetProject( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessRemoveProject( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessCommitChanged( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessFetchConfig( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessFetchKey( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessFetchBin( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
int OnProcessDownloadConfig( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
#if 0
int OnProcessAliveReportFirst( struct IbmsEnv *p_env , struct AcceptedSession *p_accepted_session );
#endif

int ShowNodes( struct IbmsEnv *p_env );
int ShowApps( struct IbmsEnv *p_env );
int ShowProjects( struct IbmsEnv *p_env );
int ShowNodesChanged( struct IbmsEnv *p_env );
int ShowSessions( struct IbmsEnv *p_env );
int AddNode( struct IbmsEnv *p_env );
int SetNode( struct IbmsEnv *p_env );
int RemoveNode( struct IbmsEnv *p_env );
int AddNodeHost( struct IbmsEnv *p_env );
int RemoveNodeHost( struct IbmsEnv *p_env );
int AddApp( struct IbmsEnv *p_env );
int SetApp( struct IbmsEnv *p_env );
int RemoveApp( struct IbmsEnv *p_env );
int AddProject( struct IbmsEnv *p_env );
int SetProject( struct IbmsEnv *p_env );
int RemoveProject( struct IbmsEnv *p_env );
int CommitChanged( struct IbmsEnv *p_env );
int DownloadConfig( struct IbmsEnv *p_env );

int LinkIbmsNodeTreeNode( struct IbmsEnv *p_env , struct IbmsNode *p_node );
struct IbmsNode *QueryIbmsNodeTreeNode( struct IbmsEnv *p_env , struct IbmsNode *p_node );
void UnlinkIbmsNodeTreeNode( struct IbmsEnv *p_env , struct IbmsNode *p_node );
struct IbmsNode *TravelIbmsNodeTreeNode( struct IbmsEnv *p_env , struct IbmsNode *p_node );
void DestroyIbmsNodeTree( struct IbmsEnv *p_env );

int LinkIbmsNodeHostTreeNode( struct IbmsNode *p_node , struct IbmsNodeHost *p_node_host );
struct IbmsNodeHost *QueryIbmsNodeHostTreeNode( struct IbmsNode *p_node , struct IbmsNodeHost *p_node_host );
void UnlinkIbmsNodeHostTreeNode( struct IbmsNode *p_node , struct IbmsNodeHost *p_node_host );
struct IbmsNodeHost *TravelIbmsNodeHostTreeNode( struct IbmsNode *p_node , struct IbmsNodeHost *p_node_host );
void DestroyIbmsNodeHostTree( struct IbmsNode *p_node );

int LinkIbmsAppTreeNode( struct IbmsEnv *p_env , struct IbmsApp *p_app );
struct IbmsApp *QueryIbmsAppTreeNode( struct IbmsEnv *p_env , struct IbmsApp *p_app );
void UnlinkIbmsAppTreeNode( struct IbmsEnv *p_env , struct IbmsApp *p_app );
struct IbmsApp *TravelIbmsAppTreeNode( struct IbmsEnv *p_env , struct IbmsApp *p_app );
void DestroyIbmsAppTree( struct IbmsEnv *p_env );

int LinkIbmsProjectTreeNode( struct IbmsEnv *p_env , struct IbmsProject *p_project );
struct IbmsProject *QueryIbmsProjectTreeNode( struct IbmsEnv *p_env , struct IbmsProject *p_project );
void UnlinkIbmsProjectTreeNode( struct IbmsEnv *p_env , struct IbmsProject *p_project );
struct IbmsProject *TravelIbmsProjectTreeNode( struct IbmsEnv *p_env , struct IbmsProject *p_project );
void DestroyIbmsProjectTree( struct IbmsEnv *p_env );

#endif

